﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Tools;
using Pixysoft.Framework.Sockets.Controller;
using System.Net.Sockets;

namespace Pixysoft.Framework.Sockets.Core
{
    class ServerSocketIoSession : SocketIoSession
    {
        public ServerSocketIoSession(ISessionEncoder encoder, ISessionDecoder decoder, Socket socket)
            : base(encoder, decoder, socket)
        {
        }

        protected override void MessageReceived(IProtocolMessage[] messages)
        {
            DateTime startTime = GlobalTimer.Instance.GetGlobalTime();// -------------------------------

            GetPerformanceAnalyzer().OnRequestArrived();

            foreach (IProtocolMessage protocolMessage in messages)
            {
                if (GetPerformanceAnalyzer().IsMaxError())
                {
                    LoggerHelper.Error(Identifier + "::socket receive max error. close connection");

                    SessionPoolController.Instance.CloseSession(this);

                    return;
                }

                try
                {
                    IActionHandler command = ActionHandlerFactory.Instance.GetHandler(
                        protocolMessage.Protocol,
                        protocolMessage.Action);

                    if (command == null)
                    {
                        LoggerHelper.Fatal(Identifier
                                  + string.Format("::unknown command {0},{1}",
                                         protocolMessage.Protocol,
                                         protocolMessage.Action));

                        GetPerformanceAnalyzer().DoError();

                        return;
                    }

                    LoggerHelper.Debug("BEGIN PROCESS:protocol:{0},action:{1},command:{2}",//
                                             protocolMessage.Protocol,
                                             protocolMessage.Action,
                                             command.GetType().Name);

                    if (protocolMessage.ByteBody != null)
                        command.Handle(this, protocolMessage, protocolMessage.ByteBody);
                    else
                        LoggerHelper.Error(Identifier + "::missing byte body for command {0},{1}", protocolMessage.Protocol, protocolMessage.Action);
                }
                catch (Exception ex)
                {
                    LoggerHelper.Fatal(Identifier + "::protocol message handle exception.");

                    LoggerHelper.Fatal(ex);

                    GetPerformanceAnalyzer().DoError();

                    continue;
                }
            }

            TimeSpan processSpan = GlobalTimer.Instance.GetGlobalTime() - startTime;

            long processInterval = processSpan.Milliseconds;// ----------------------

            GlobalPerformanceAnalyzer.Instance.OnProcessEnd(processInterval);
        }

        public static ISocketIoSession CreateSession(ISessionEncoder encoder, ISessionDecoder decoder, Socket socket)
        {
            return new ServerSocketIoSession(encoder, decoder, socket);
        }
    }
}
